home *** CD-ROM | disk | FTP | other *** search
- ⓪ MODULE CmpMods2; (*$Z+,M+,C-,Q+,P+,V+,R-*)⓪ ⓪ FROM InOut IMPORT Write, WriteLn, WriteString, WriteInt, WriteCard,⓪"OpenOutput, CloseOutput;⓪ ⓪ FROM SYSTEM IMPORT ASSEMBLER, ADDRESS, WORD, BYTE, ADR, TSIZE, LONGWORD, CAST;⓪ FROM SysTypes IMPORT PtrAnyLongType;⓪ FROM ArgCV IMPORT PtrArgStr, InitArgCV;⓪ FROM Storage IMPORT ALLOCATE, DEALLOCATE, MemAvail;⓪ FROM Strings IMPORT Upper, Concat, Compare, Relation, Pos, Empty,⓪7StrEqual, Split, Assign, Copy, PosLen, String, Append;⓪ IMPORT FastStrings;⓪ FROM Files IMPORT Open, Create, Access, Close, Remove, FILE, ReplaceMode,⓪(State, ResetState;⓪ FROM Paths IMPORT SearchFile, ListPos;⓪ FROM PathEnv IMPORT ReplaceHome, HomePath;⓪ FROM PathCtrl IMPORT PathList;⓪ FROM Directory IMPORT MakeFullPath;⓪ FROM FileNames IMPORT SplitPath, SplitName, ConcatName, ConcatPath,⓪(FileSuffix;⓪ FROM Binary IMPORT ReadBytes, WriteBytes, Seek, SeekMode, FileSize, WriteBlock;⓪ FROM ShellMsg IMPORT ModPaths, ImpPaths, LLRange, ShellPath, LinkerParm;⓪ FROM MOSCtrl IMPORT PDB;⓪ FROM PrgCtrl IMPORT TermProcess;⓪ FROM MOSConfig IMPORT DftSfx, ImpSfx, MaxBlSize;⓪ IMPORT MOSGlobals, StrConv, Block;⓪ FROM MM2LnkIO IMPORT ClearEOP, Report, Prompt, InitOutput, VerboseOutput,⓪(Read, ReadString, WriteString, WriteMod,⓪(ClearMod, DiscardMods, ReportRealFormat, BeginWriting, ReportCodeLen,⓪(ReportLinkError, ReportIOError, ReportError, WritingOut, EndWriting;⓪ CONST PDBlayout = 4;⓪&version = '2.17'; (* Linker-Version *)⓪&CodeID = "Megamax Modula-2 V2";⓪ ⓪ VAR ok: BOOLEAN;⓪ ⓪ ⓪ PROCEDURE conc (a,b:ARRAY OF CHAR):String;⓪"VAR c:String;⓪"BEGIN⓪$concat (a,b,c,ok);⓪$RETURN c⓪"END conc;⓪ ⓪ ⓪ CONST⓪ ⓪"SysVarSpace = 52; (* layout,⓪>^basePage (f. ArgV),⓪>^modList (f. Loader),⓪>Anzahl der Einträge in modLst,⓪>processState,⓪>BottomOfStack,⓪>TopOfStack,⓪>termState,⓪>resident,⓪>flags,⓪>TermProcs,⓪>^prev,⓪>16 reserved bytes *)⓪ ⓪"ShModLstSpace = 14; (* head0: ADDRESS;⓪>var0: ADDRESS;⓪>varlen0: LONGCARD;⓪>flags: BITSET; *)⓪ ⓪(ESC = 33C;⓪ ⓪%BadIndex = 1000;⓪'anykey = 0L; (* Joker fuer Modul-Key *)⓪$DefOutSuf = '.PRG'; (* Suffix f. Output, wenn keiner angegeben *)⓪ ⓪ VAR DefImpInSuf: ARRAY [0..2] OF CHAR; (* Suffix fuer Input Impl. Files *)⓪$DefPrgInSuf: ARRAY [0..2] OF CHAR; (* Suffix fuer Input Main Files *)⓪ ⓪&ListMax: CARDINAL; (* ehemals konstant 1000 *)⓪ ⓪ TYPE⓪'tIndex = [0..BadIndex]; (* Index auf die Modul-Liste; BadIndex⓪Ckodiert Sonderfaelle: kein gueltiger⓪CIndex bzw. residentes Modul *)⓪%tModName = string;⓪ ⓪%ptrModDesc = POINTER TO tModDesc;⓪ ⓪%tModDesc = RECORD⓪2image: address; (* ^Buffer beim Relozieren *)⓪1codeAd: address; (* StartAdr im ROM *)⓪0codeEnd: LONGCARD;⓪2varAd: address; (* StartAdr der Variablen *)⓪1varLen: LONGCARD; (* Länge der Variablen *)⓪3diff: longcard; (* Laenge der entfernten Imp.Liste *)⓪4key: longcard; (* Key dieses Moduls *)⓪1modlen: longcard; (* Code-Länge dieses Moduls *)⓪-sourcename: ARRAY [0..11] OF CHAR;⓪-symbolname: ARRAY [0..11] OF CHAR;⓪3name: ARRAY [0..39] OF CHAR; (* ModulName *)⓪0procSym: BOOLEAN;⓪/compopts: LONGWORD;⓪.mayRemove: BOOLEAN; (* FALSE: Body keinesfalls wegoptimieren!*)⓪0mainMod: BOOLEAN; (* FALSE: ist'n importiertes Modul *)⓪.mayCrunch: BOOLEAN; (* TRUE: Proc-Length-Liste vorhanden *)⓪/crunched: BOOLEAN;⓪+varsExported: BOOLEAN; (* TRUE: Vars werden v. anderen Mods importiert *)⓪0useCode: BOOLEAN; (* FALSE: Modulcode wird nicht gebraucht *)⓪-bodyMarked: BOOLEAN;⓪1ImpLst: POINTER TO ARRAY tIndex OF tIndex; (* Liste der imp. Module *)⓪/ImpIndex: tIndex; (* Anzahl imp. Module *)⓪/finalIdx: tIndex; (* Index für ModBase *)⓪0END;⓪ ⓪$ErrType = (NotFound, BadFormat, BadVersion, NoSpace, TooManyMods,⓪1mustnotbeimpl, badlayout, readerr, relocerr, nooptimize,⓪1badReal);⓪0⓪(pLONG = POINTER TO LONGCARD;⓪ ⓪ VAR⓪'ModLst: POINTER TO ARRAY tIndex OF tModDesc; (* Liste der geladenen Module *)⓪%ModIndex: tIndex; (* ^ letzten Eintrag in ModLst *)⓪$UsedCodes: tIndex; (* Anzahl der verw. Modulcodes *)⓪&InitLst: POINTER TO ARRAY tIndex OF tIndex; (* Liste der Init-Reihenfolge *)⓪$InitIndex: tIndex; (* ^ letzten Eintrag in InitLst *)⓪%InitIdx2: tIndex; (* ^ auf Second-Mod - InitLst *)⓪$UsedInits: tIndex; (* Anzahl der zu init. Bodies *)⓪ ⓪#CodeSuffix: boolean;⓪"LoadingMain: BOOLEAN;⓪%IOResult,⓪*ior: INTEGER; (* ZW fuer IOResults *)⓪ ⓪%LoadFile, (* geladene Module *)⓪&OutFile: file; (* zu schreibendes Codefile *)⓪ ⓪%BSSstart: address; (* Start-Adr fuer reloz. Vars *)⓪&CodeNow, (* ^ zu vergebenden Codeplatz *)⓪'VarNow: address; (* ^ zu vergebenden Varplatz *)⓪"ShModLstLen: Longcard; (* Ges.länge der ModLst f.d. Loader *)⓪$stacksize: LONGCARD;⓪ ⓪&BodyLen: LONGCARD; (* testweise f. Länge aller Bodies *)⓪"⓪&pRelTab,⓪&eRelTab,⓪%RelocTab: ADDRESS;⓪!firstRelVal : longcard;⓪"lastRelVal : longcard;⓪!⓪&dt_buf : RECORD (* disk transfer buffer *)⓪1dum0 : ARRAY [1..13] OF word;⓪1flen : LONGCARD;⓪1dum1 : ARRAY [16..22] OF word⓪/END;⓪&⓪%singleMod: BOOLEAN;⓪%⓪)paths: PathList;⓪ ⓪&optProcs: BOOLEAN; (* TRUE: Procs optimieren *)⓪&noHeader: BOOLEAN; (* TRUE: Header aus Moduln entfernen *)⓪$noShModLst: BOOLEAN; (* TRUE: ShortModList aus Moduln entfernen *)⓪$noProcSyms: BOOLEAN; (* TRUE: ProcSymbols vor Prozeduren entfernen *)⓪ ⓪"extendedCode: BOOLEAN;⓪&realForm: CARDINAL;⓪ ⓪#HeaderFlags: BITSET;⓪ ⓪ ⓪ PROCEDURE fputm ( f:file; VAR p:ARRAY OF word; c:LONGCARD );⓪"BEGIN⓪$WriteBytes (f, ADR (p), c);⓪"END fputm;⓪ ⓪ ⓪ PROCEDURE fput ( f:file; REF p: ARRAY OF BYTE );⓪"BEGIN⓪$IF NOT ODD (HIGH (p)) THEN HALT END;⓪$WriteBlock (f, p);⓪"END fput;⓪ ⓪ ⓪ PROCEDURE hasSuffix (s: string): boolean;⓪"VAR p: cardinal;⓪"BEGIN⓪$RETURN length (FileSuffix (s)) > 0;⓪$(* in den letzten 4 Zeichen von s muss ein Punkt stehen! *)⓪"END hasSuffix;⓪ ⓪ ⓪ PROCEDURE entry (Index: address; Displacement: LONGCARD): LongCard;⓪"(*** Long-Peek mit Displacement ***)⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.L -(A3),A0⓪(ADDA.L -(A3),A0⓪(MOVE.L (A0),D0⓪$END⓪"END entry;⓪"(*$L=*)⓪ ⓪ ⓪ PROCEDURE enter (Index: address; Displacement: cardinal; value: LongCard);⓪"(*** Long-Poke mit Displacement ***)⓪"VAR p: POINTER TO LongCard;⓪"BEGIN⓪$p:= Index + address (long (Displacement));⓪$p^:= value;⓪"END enter;⓪ ⓪ ⓪ PROCEDURE error (client, impmod: ARRAY OF CHAR; t: ErrType);⓪ ⓪"(*** Fehleranzeige auf dem Bildschirm; danach zurueck zum Aufrufer ***)⓪"⓪"VAR msg: String;⓪"⓪"BEGIN⓪$CASE t OF⓪+badReal: msg:= 'Different real-formats specified'; client[0]:= 0C |⓪(badversion: msg:= 'Wrong module version' |⓪)badformat: msg:= 'Wrong module format'; client[0]:= 0C |⓪*notfound: msg:= 'Module not found'; client[0]:= 0C |⓪+readerr: msg:= 'File is damaged'; client[0]:= 0C |⓪+nospace: msg:= 'Out of memory'; client[0]:= 0C |⓪'toomanymods: msg:= 'Too many modules (enlarge "max. Module")'; client[0]:= 0C|⓪%mustnotbeimpl: msg:= 'Init-module must be program module'; client[0]:= 0C|⓪)badlayout: msg:= 'Bad module layout'; client[0]:= 0C|⓪*relocerr: msg:= 'Error in relocation list'; client[0]:= 0C|⓪(nooptimize: msg:= 'Old module layout - may not be optimized'; client[0]:= 0C|⓪$END; (* of case *)⓪$ReportLinkError (impmod, client, msg)⓪"END error;⓪ ⓪ ⓪ PROCEDURE MyError (ior: integer);⓪"BEGIN⓪$ReportIOError (ior)⓪"END MyError;⓪ ⓪ PROCEDURE RelError0 (REF s: ARRAY OF CHAR);⓪"BEGIN⓪$ReportError (s);⓪$Remove (outfile);⓪$TermProcess (MOSGlobals.OutOfMemory)⓪"END RelError0;⓪ ⓪ PROCEDURE RelError (internalErr: BOOLEAN);⓪"VAR s: String;⓪"BEGIN⓪$s:= 'Out of memory!';⓪$IF internalErr THEN Append (' (internal error!)', s, ok) END;⓪$RelError0 (s);⓪"END RelError;⓪ ⓪ PROCEDURE RelError2;⓪"BEGIN⓪$RelError0 ('Relocation table overflow! Use "-R" option.');⓪"END RelError2;⓪ ⓪ ⓪ PROCEDURE GetStr (VAR p: address): tModName;⓪"(* String aus der Importliste holen *)⓪"VAR s: tModName;⓪"BEGIN⓪$ASSEMBLER⓪,MOVE.L p(A6),A1 ;Adresse von p⓪,MOVE.L (A1),A2 ;Wert von p⓪,LEA s(A6),A0⓪%!RE13 MOVE.B (A2)+,D2 ;Zeichen holen⓪,CMPI.B #$FE,D2⓪,BCC RE12 ; -> Endmarke⓪,MOVE.B D2,(A0)+⓪,BRA RE13⓪%!RE12 BNE RE14⓪,ADDQ.L #1,A2⓪%!RE14 CLR.B (A0)+⓪,MOVE.L A2,(A1) ;p hochsetzen⓪$END;⓪$RETURN s⓪"END GetStr;⓪ ⓪ PROCEDURE SkipStr (VAR p: address);⓪"(* String aus der Importliste überspringen *)⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪,MOVE.L -(A3),A1 ;Adresse von p⓪,MOVE.L (A1),A2 ;Wert von p⓪%!RE13 CMPI.B #$FF,(A2)+⓪,BNE RE13⓪,MOVE.L A2,(A1) ;p hochsetzen⓪$END;⓪"END SkipStr;⓪"(*$L=*)⓪ ⓪ PROCEDURE SkipImpList (VAR p: address);⓪"(* Importliste überspringen *)⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.L -(A3),A0⓪(MOVE.L (A0),A1⓪%R6 MOVE.W (A1)+,D0 ;imp. ItemNr⓪(BEQ R5 ;fertig mit diesem Import⓪(MOVE.L (A1)+,D1 ;importiertes Item⓪(BRA R6⓪%R5 MOVE.L A1,(A0)⓪$END;⓪"END SkipImpList;⓪"(*$L=*)⓪ ⓪ ⓪ PROCEDURE SplitFileName ( REF Source: ARRAY OF CHAR; VAR Name,sfx: ARRAY OF Char );⓪"VAR dummy: MOSGlobals.PathStr;⓪"BEGIN⓪$SplitPath (source, dummy, name);⓪$SplitName (name, name, sfx)⓪"END SplitFileName;⓪ ⓪ ⓪ ⓪ PROCEDURE moveMem (olo, ohi, nlo: LONGCARD);⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.L olo(A6),A0⓪(MOVE.L ohi(A6),A1⓪(MOVE.L nlo(A6),A2⓪&L MOVE.W (A0)+,(A2)+⓪(CMPA.L A1,A0⓪(BCS L⓪$END⓪"END moveMem;⓪ ⓪ ⓪ PROCEDURE isCLinkMod (modidx: CARDINAL): BOOLEAN;⓪ (*⓪!* Wert: TRUE, wenn Modul von 'MM2CLink' erzeugt wurde.⓪!*)⓪"BEGIN⓪$RETURN entry (ModLst^ [modidx].image, 50) # 0;⓪"END isCLinkMod;⓪ ⓪ ⓪ PROCEDURE Vergleiche;⓪ ⓪"TYPE RelocList = POINTER TO RECORD link: LONGCARD; procAddr: LONGCARD END;⓪'ProcLenList = POINTER TO RECORD start: LONGCARD; len: LONGCARD END;⓪'ImportTable = POINTER TO RECORD item: CARDINAL; procAddr: LONGCARD END;⓪$⓪"PROCEDURE pStart (p: ProcLenList): LONGCARD;⓪$(*$L-*)⓪$BEGIN⓪&ASSEMBLER⓪(MOVE.L -(A3),A0⓪(MOVE.L (A0),D0 ; p^.start⓪(ANDI.L #$00FFFFFF,D0⓪&END;⓪$END pStart;⓪$(*$L=*)⓪ ⓪"PROCEDURE pEnd (p: ProcLenList): LONGCARD;⓪$(*$L-*)⓪$BEGIN⓪&ASSEMBLER⓪(MOVE.L -(A3),A0⓪(MOVE.L (A0)+,D0 ; p^.start⓪(ANDI.L #$00FFFFFF,D0⓪(ADD.L (A0),D0 ; p^.len⓪&END;⓪$END pEnd;⓪$(*$L=*)⓪ ⓪"PROCEDURE mark (p: ProcLenList; n: CARDINAL);⓪$(* n: 1='lokal verwendet', 2='von anderem Modul importiert' *)⓪$(*$L-*)⓪$BEGIN⓪&ASSEMBLER⓪(MOVE.W -(A3),D0⓪(MOVE.L -(A3),A0⓪(MOVE.B D0,(A0) ; p^.start⓪&END;⓪$END mark;⓪$(*$L=*)⓪ ⓪"PROCEDURE marked (p: ProcLenList): BOOLEAN;⓪$(*$L-*)⓪$BEGIN⓪&ASSEMBLER⓪(MOVE.L -(A3),A0⓪(TST.B (A0) ; p^.start⓪(SNE D0⓪(ANDI #1,D0⓪&END;⓪$END marked;⓪$(*$L=*)⓪ ⓪"PROCEDURE markedValue (p: ProcLenList): CARDINAL;⓪$(*$L-*)⓪$BEGIN⓪&ASSEMBLER⓪(MOVE.L -(A3),A0⓪(CLR D0⓪(MOVE.B (A0),D0 ; p^.start⓪&END;⓪$END markedValue;⓪$(*$L=*)⓪ ⓪"PROCEDURE between (v, lo, hi: LONGCARD): BOOLEAN;⓪$(*$L-*)⓪$BEGIN⓪&ASSEMBLER⓪(MOVE.L -(A3),D0 ; hi⓪(MOVE.L -(A3),D1 ; lo⓪(MOVE.L -(A3),D2 ; v⓪(CMP.L D1,D2⓪(BCS fals⓪(CMP.L D0,D2⓪(BCC fals⓪(MOVEQ #1,D0⓪(RTS⓪&fals⓪(CLR D0⓪&END;⓪$END between;⓪$(*$L=*)⓪ ⓪"PROCEDURE advance (p: LONGCARD; VAR prl: ProcLenList);⓪$(*$L-*)⓪$BEGIN⓪&ASSEMBLER⓪(MOVE.L -(A3),A2 ; ADR (prl)⓪(MOVE.L -(A3),-(A7) ; p⓪(MOVE.L (A2),A1⓪&lupo⓪(MOVE.L (A7),(A3)+⓪(MOVE.L A1,(A3)+⓪(BSR pStart/⓪(MOVE.L D0,(A3)+⓪(MOVE.L A1,(A3)+⓪(BSR pEnd/⓪(MOVE.L D0,(A3)+⓪(BSR between/⓪(BNE ende⓪(ADDQ.L #8,A1⓪(BRA lupo⓪&ende⓪(MOVE.L A1,(A2)⓪(ADDQ.L #4,A7⓪&END⓪&(*⓪&WHILE NOT between (p, pStart (prl), pEnd (prl)) DO⓪(INC (prl, SHORT (SIZE (prl^)))⓪&END;⓪&*)⓪$END advance;⓪$(*$L=*)⓪ ⓪"PROCEDURE findListEntry (idx: tIndex; ad: LONGCARD; VAR prl: ProcLenList);⓪$BEGIN⓪&WITH ModLst^ [idx] DO⓪(prl:= image + entry (image, 38)⓪&END;⓪&advance (ad, prl)⓪$END findListEntry;⓪ ⓪ ⓪$VAR⓪&image1, image2: ADDRESS;⓪&pra1, pra2: RelocList;⓪&prl1, prl2: ProcLenList;⓪&link1, link2: LONGCARD;⓪ ⓪"BEGIN (* Vergleiche *)⓪$image1:= ModLst^ [1].image;⓪$image2:= ModLst^ [2].image;⓪$⓪$pra1:= image1 + entry (image1, 22);⓪$prl1:= image1 + entry (image1, 38);⓪$⓪$pra2:= image2 + entry (image2, 22);⓪$prl2:= image2 + entry (image2, 38);⓪$⓪$OpenOutput ('TXT');⓪$⓪$WHILE pra1^.link # NIL DO⓪&IF pra1^.procAddr < entry (image1, 22) THEN (* Proc, nicht Var *)⓪(advance (pra1^.procAddr, prl1);⓪(link1:= pra^.link1;⓪(LOOP⓪*IF link = 0L THEN⓪,EXIT⓪*ELSIF between (link, start, ende) THEN⓪,IF ~marked (prl) THEN⓪.mark (prl,1);⓪.markCalls (modidx, pStart (prl), pEnd (prl))⓪,END;⓪,EXIT⓪*END;⓪*link:= entry (image, link)⓪(END⓪&END;⓪&INC (pra, 8)⓪$END;⓪ ⓪$CloseOutput;⓪ ⓪"END Vergleiche;⓪ ⓪ ⓪ PROCEDURE bit (n: CARDINAL; l: ARRAY OF WORD): BOOLEAN;⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.W -(A3),D2⓪(MOVE.L -(A3),A0⓪(MOVE.W -(A3),D1⓪(TST D2⓪(BEQ wd⓪(MOVE.L (A0),D0⓪(BRA lg⓪%wd MOVE.W (A0),D0⓪%lg BTST D1,D0⓪(SNE D0⓪(ANDI #1,D0⓪$END⓪"END bit;⓪"(*$L=*)⓪ ⓪ ⓪ PROCEDURE ExecMod (mname: tModName; (* Name des gewuenschten Moduls *)⓪2reqkey: LONGCARD; (* gewuenschter Key *)⓪2client: tIndex) (* Index des Klienten *)⓪8: tIndex; (* vergebener Index *)⓪ ⓪"(* Laedt das Modul "mname" und liefert dessen Index in der "ModLst"⓪#* als Ergebnis.⓪#* Der Modulkey "reqkey" wird erwartet und ueberprueft.⓪#* Falls ein Fehler beim Relozieren oder Laden auftritt,⓪#* wird der benoetigte Speicher freigegeben und als Ergebnis⓪#* "BadIndex" geliefert⓪#*)⓪$⓪"VAR⓪.i: tIndex;⓪%clientname,⓪*fname: tModName;⓪-ad: address;⓪"⓪$⓪"PROCEDURE LoadMod (mname, fname: tModName): tIndex;⓪ ⓪$(* Laedt ein Modul in den Speicher, ueberprueft das Format⓪%* und traegt in die Modul-Liste ein. Reloziert nicht!⓪%* Wenn ein Fehler auftritt, wird der benutzte Speicher⓪%* freigegeben und als Modul-Index BadIndex geliefert⓪%*)⓪ ⓪$PROCEDURE ImportLen (image: address): LongCard;⓪&⓪&(* Laenge der Importliste des Moduls, das bei image steht,⓪)in Bytes ermitteln⓪&*)⓪&⓪&VAR s: address; n: LONGCARD;⓪&⓪&BEGIN⓪(s:= entry (image, 14);⓪(IF s = NIL THEN⓪*RETURN 0L⓪(ELSE⓪*n:= 4; (* Platz für Import-Liste (s. PutMod) *)⓪*s:= s+image;⓪*WHILE entry (s, 0) # 0L DO⓪,inc (s, 4);⓪,WHILE cardinal (s^) MOD 256 # 255 DO inc (s, 2) END;⓪,inc (s, 2);⓪,WHILE cardinal (s^) # 0 DO inc (s, 6) END;⓪,inc (s, 2);⓪,INC (n, 4);⓪*END;⓪*RETURN s+4L-image-entry (image, 14) - n⓪(END⓪&END ImportLen;⓪$⓪$VAR foundkey: LongCard; (* Key des geladenen Moduls *)⓪-ModAdr: Address; (* Anfang des geladenen Moduls *)⓪.found: Boolean; (* fuer FileSearch *)⓪,DriveNr: Cardinal; (* " *)⓪.VolNr: Cardinal; (* " *)⓪0ad1: address; (* fuer Storage-Anforderungen *)⓪0len: longcard; (* -"- *)⓪-layout: CARDINAL;⓪+realCode: CARDINAL;⓪-mname0: POINTER TO tModName;⓪,badFile: BOOLEAN;⓪-dummys: ARRAY [0..127] OF CHAR;⓪$⓪$BEGIN (* LoadMod *)⓪&IF ModIndex < LinkerParm.maxLinkMod THEN⓪(inc (ModIndex);⓪&ELSE⓪((*** Leider ist die Liste übergelaufen: ***)⓪(error (clientname, mname, TooManyMods);⓪(DeAllocate (ad1,0L);⓪(RETURN BadIndex⓪&END;⓪&⓪&SearchFile (fname,paths,fromStart,found,fname);⓪&Open (loadFile,fname,readonly);⓪&IF state (loadfile) < 0 THEN⓪(error (clientname,mname,notfound);⓪(RETURN BadIndex⓪&END;⓪ ⓪&len:= FileSize (loadFile);⓪&Allocate (ad1, len);⓪&IF ad1 = NIL THEN⓪(Close (loadFile);⓪(error (clientname,mname,nospace);⓪(RETURN BadIndex⓪&END;⓪ ⓪&ReadBytes (loadFile, ad1, len, len);⓪&ior:= State (loadFile);⓪&ResetState (loadFile);⓪&Close (loadFile);⓪&IF IOR<0 THEN⓪(error (clientname,mname,readerr);⓪(DeAllocate (ad1,0L);⓪(RETURN BadIndex⓪&END;⓪ ⓪&ASSEMBLER⓪(MOVE.L ad1(A6),A0⓪(CMPI.L #$4D4D3243,(A0)+ ; "MM2C"⓪(BNE nocode⓪(CMPI.L #$6F646500,(A0)+ ; "ode"⓪&nocode⓪(SNE D0⓪(ANDI #1,D0⓪(MOVE D0,badFile(A6)⓪&END;⓪&IF badFile THEN⓪(error (clientname,mname,badlayout);⓪(DeAllocate (ad1,0L);⓪(RETURN BadIndex⓪&END;⓪ ⓪&ModAdr:= ad1+8L;⓪ ⓪&layout:= Short (entry (ModAdr, 0) DIV 65536L);⓪&ASSEMBLER⓪(MOVE.W layout(A6),D0⓪(LSR.B #5,D0⓪(ANDI #3,D0⓪(MOVE.W D0,realCode(A6)⓪&END;⓪&(*⓪(IF (layout DIV 256) < 1 THEN⓪*error (clientname,mname,badlayout);⓪*DeAllocate (ad1,0L);⓪*RETURN BadIndex⓪(END;⓪&*)⓪&⓪&IF singleMod THEN⓪(singleMod:= FALSE;⓪&END;⓪&⓪&IF realCode # 0 THEN (* real im Code *)⓪(IF realForm # 0 THEN (* schon Real benutzt *)⓪*IF realCode # realForm THEN⓪,error (clientname,mname,badreal);⓪,DeAllocate (ad1,0L);⓪,RETURN BadIndex⓪*END⓪(ELSE⓪*ReportRealFormat (realCode-1);⓪*realForm:= realCode⓪(END⓪&END;⓪&⓪&foundkey:= entry (ModAdr, 2);⓪&IF (reqkey#anykey) & (reqkey#foundkey) THEN⓪(error (clientname,mname,badversion);⓪(DeAllocate (ad1,0L);⓪(RETURN BadIndex⓪&END;⓪&⓪&(*** Modul in ModLst eintragen ***)⓪*⓪&WITH ModLst^ [ModIndex] DO⓪(mainMod:= LoadingMain;⓪(useCode:= TRUE;⓪(varsExported:= FALSE;⓪(image := ModAdr;⓪(mayCrunch:= (layout DIV 256) >= 2;⓪(IF optProcs AND NOT mayCrunch THEN⓪*error (clientname,mname,nooptimize);⓪*RETURN BadIndex⓪(END;⓪(IF noHeader AND mayCrunch THEN⓪*diff:= entry (image, 42) (* ganzen Header weglassen *)⓪(ELSE⓪*diff:= ImportLen (image)⓪(END;⓪(codeEnd:= entry (ModAdr, 22);⓪(BodyLen:= BodyLen + (codeEnd - entry (ModAdr, 6));⓪(varAd := VarNow;⓪(varLen:= entry (ModAdr, 10) - entry (ModAdr, 22);⓪(key := foundkey;⓪(mname0:= ADDRESS (entry (ModAdr, 26)) + ModAdr;⓪(SplitPath (mname0^,dummys,sourcename);⓪(mname0:= ADDRESS (entry (ModAdr, 30)) + ModAdr;⓪(Assign (mname0^,name,ok);⓪(mname0:= ADDRESS (entry (ModAdr, 34)) + ModAdr;⓪(SplitPath (mname0^,dummys,symbolname);⓪(compopts:= LONGWORD (entry (ModAdr, 46));⓪(mayRemove:= NOT bit (2, compopts);⓪(procSym:= bit (4, layout);⓪(bodyMarked:= FALSE;⓪(useCode:= TRUE;⓪(crunched:= FALSE;⓪(ImpIndex:= 0;⓪(ImpLst:= NIL;⓪(varNow:= varNow + varlen;⓪(IF isCLinkMod (ModIndex) THEN⓪*WriteMod (ModIndex, conc ('©', name), fname);⓪(ELSE⓪*WriteMod (ModIndex, name, fname);⓪(END;⓪&END;⓪&LoadingMain:= FALSE;⓪&RETURN ModIndex;⓪$END LoadMod;⓪ ⓪ ⓪"PROCEDURE ImportMods (myIndex: tIndex): Boolean;⓪"⓪$VAR ReqKey: LongCard;⓪)ImPtr: address;⓪'ImIndex: tIndex;⓪,ok: boolean;⓪-i: cardinal;⓪ ⓪$BEGIN⓪&WITH ModLst^ [myIndex] DO⓪((* Anzahl der importierten Module bestimmen *)⓪((* und entspr. Speicher allozieren *)⓪(ImPtr:= image + entry (image, 14); (* ^ImportListe *)⓪(ReqKey:= entry (ImPtr, 0); (* importiertes Modul *)⓪(i:= 2;⓪(WHILE ReqKey # 0L DO⓪*inc (ImPtr, 4);⓪*SkipStr (ImPtr);⓪*SkipImpList (ImPtr);⓪*inc(i);⓪*ReqKey:= entry (ImPtr, 0)⓪(END; (* alle Importe abgearbeitet *)⓪(ALLOCATE (ImpLst, LONG (i) * TSIZE (tIndex));⓪(IF ImpLst = NIL THEN⓪*error (clientname,name,nospace)⓪(END;⓪ ⓪(ImPtr:= image + entry (image, 14); (* ^ImportListe *)⓪(ReqKey:= entry (ImPtr, 0); (* importiertes Modul *)⓪(ok:= true;⓪(WHILE (ReqKey # 0L) & ok DO⓪*inc (ImPtr, 4);⓪*ImIndex:= ExecMod (getstr (ImPtr), ReqKey, myIndex);⓪*IF ImIndex # BadIndex THEN⓪,SkipImpList (ImPtr);⓪,inc(ImpIndex);⓪,ImpLst^[ImpIndex]:= ImIndex⓪*ELSE⓪,ok:= false⓪*END;⓪*ReqKey:= entry (ImPtr, 0)⓪(END; (* alle Importe abgearbeitet *)⓪&END;⓪&RETURN ok⓪$END ImportMods;⓪"⓪"VAR s1,s2: tModName;⓪"⓪"BEGIN (* of ExecMod *)⓪$IF codesuffix THEN⓪&paths:= ImpPaths;⓪&ConcatName (mname, DefImpInSuf, fname)⓪$ELSE⓪&fname:= mname;⓪&SplitFileName (fname, mname, s1);⓪&Upper (s1);⓪&IF StrEqual (s1,DefImpInSuf) THEN⓪(paths:= ImpPaths⓪&ELSE⓪(paths:= ModPaths⓪&END⓪$END;⓪$codesuffix:= true;⓪$⓪$i:= LoadMod (mname, fname);⓪$IF i # BadIndex THEN (* Load war erfolgreich *)⓪&RETURN i⓪$ELSE (* Load ist schiefgegangen *)⓪&RETURN BadIndex⓪$END⓪"END ExecMod;⓪ ⓪ ⓪ ⓪ (*$L-,R-*)⓪ PROCEDURE PutIntoRelTab ( v: longcard );⓪"(* VAR d:longcard; *)⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.L -(A3),D0⓪(TST.L firstRelVal⓪(BNE c0⓪(MOVE.L D0,firstRelVal⓪(BRA e0⓪ c0 CMP.L lastRelVal,D0⓪(BHI c1⓪ jErr CLR (A3)+⓪(JMP RelError ; Programmende⓪ c1 MOVE.L D0,D1⓪(SUB.L lastRelVal,D1⓪(⓪(MOVE.L pRelTab,A0⓪ l1 CMPA.L eRelTab,A0⓪(BCC jErr ; Listenüberlauf⓪(CMPI.L #256,D1⓪(BCS c2⓪(MOVE.B #1,(A0)+⓪(SUBI.L #254,D1⓪(BRA l1⓪ c2 MOVE.B D1,(A0)+⓪(MOVE.L A0,pRelTab⓪ ⓪ e0 MOVE.L D0,lastRelVal⓪$END⓪"END PutIntoRelTab;⓪ (*$L+,R+*)⓪ ⓪ ⓪ (*⓪!* Globale Vars:⓪!*)⓪ VAR ListTop: POINTER TO ARRAY [1..100000] OF pLONG;⓪'ListBeg: POINTER TO ARRAY [1..100000] OF pLONG;⓪%ListIndex: cardinal;⓪&LastDrop: pLONG;⓪)eoLists, Lists: pLONG;⓪ ⓪ ⓪ PROCEDURE dialog(): Boolean;⓪ ⓪"(*$R-*)⓪"PROCEDURE ClrList;⓪$VAR i : cardinal;⓪$BEGIN⓪&FOR i:= 1 TO ListIndex DO⓪(ListTop^[i]:= NIL⓪&END;⓪&ListIndex:= 0;⓪&LastDrop:= Lists⓪$END ClrList;⓪ ⓪"(*$R-,L-*)⓪"PROCEDURE SmallestInList() : LONGCARD;⓪$BEGIN⓪&ASSEMBLER⓪(MOVEQ #-1,D0⓪(CLR.W D1⓪(MOVEQ #1,D2⓪&forloop0⓪(CMP listIndex,D2⓪(BHI forend0⓪(MOVE D2,D3⓪(SUBQ #1,D3⓪(ASL #2,D3⓪(MOVE.L ListTop,A0⓪(MOVE.L 0(A0,D3.W),A1⓪(CMPA.L #NIL,A1⓪(BEQ cont0⓪(MOVE.L (A1),D4⓪(CMP.L D4,D0⓪(BLS cont0⓪(MOVE.L D4,D0⓪(MOVE D2,D1⓪&cont0⓪(ADDQ #1,D2⓪(BRA forloop0⓪&forend0⓪(TST D1⓪(BEQ ende⓪(SUBQ #1,D1⓪(ASL #2,D1⓪(MOVE.L ListTop,A0⓪(MOVE.L 0(A0,D1.W),D2⓪(MOVE.L ListBeg,A1⓪(CMP.L 0(A1,D1.W),D2⓪(BNE cont1⓪(CLR.L 0(A0,D1.W)⓪(BRA cont2⓪&cont1⓪(SUBQ.L #4,0(A0,D1.W)⓪&cont2⓪(RTS⓪&ende⓪(CLR.L D0⓪&END⓪$END SmallestInList;⓪"⓪"(*$R-,L+*)⓪"PROCEDURE reloc (myMod, imMod: ptrModDesc; VAR ImPtr: ADDRESS; VAR ok: BOOLEAN);⓪$BEGIN⓪&ASSEMBLER⓪(MOVEM.L D3/D4/D6/A4/A5,-(A7)⓪ ⓪(MOVE.L myMod(A6),A4⓪(MOVE.L tModDesc.image(A4),A4 ;^ zu relozierendes Modul⓪(⓪(MOVE.L ImPtr(A6),A1⓪(MOVE.L (A1),A1⓪(MOVEQ #1,D6 ;noch ist alles 'ok'⓪(⓪(MOVE.L A6,-(A7)⓪(MOVE.L imMod(A6),A6 ;A6 ist ^ModLst^ [ImIndex]⓪(MOVE.L tModDesc.image(A6),A2 ;A2 zeigt auf imp. Modul⓪!⓪!!RE6 MOVE.W (A1)+,D0 ;imp. ItemNr⓪(BEQ.L RE5 ;fertig mit diesem Import⓪(MOVE.L 18(A2),D3 ;Offset zur Exp.liste⓪(BEQ.L BAD ;keine da⓪(ADD.L A2,D3⓪(MOVE.L (A1)+,D1 ;importiertes Item⓪(BEQ RE6 ; wird gar nicht benutzt⓪ ⓪(MOVE ListIndex,D4⓪(CMP.W ListMax,D4⓪(BCC.W relerr2⓪(ADDQ #1,ListIndex⓪(MOVE.L ListBeg,A5⓪(MOVE ListIndex,D4⓪(SUBQ #1,D4⓪(LSL #2,D4⓪(CLR.L 0(A5,D4.W)⓪ ⓪(MOVE.L D3,A0⓪!!RE9 MOVE.W (A0)+,D2 ;Item in Exportliste suchen⓪(BEQ.W BAD ; schade - Liste zuende⓪(CMP.W D2,D0⓪(BEQ RE10 ;gefunden⓪(ADDQ.L #4,A0⓪(BRA RE9⓪!!RE10 MOVE.L (A0)+,D2 ;abs. ItemAdr ausrechnen⓪(BEQ re6 ;wurde wegoptimiert⓪(CMP.L 22(A2),D2⓪(BCC isVa2 ;das ist eine Var-Referenz⓪(ADD.L tModDesc.codeAd(A6),D2 ;Prozeduren: + Modulanfang⓪(SUB.L tModDesc.diff(A6),D2 ; - Importlisten-Laenge⓪(BRA RE11⓪!!isVa2 ADD.L tModDesc.varAd(A6),D2 ;Variablen: + VarAnfang⓪(ADD.L BSSstart,D2 ;Codelänge addieren⓪(SUB.L 22(A2),D2⓪!!RE11 CMP.L 22(A4),D1 ;liegt Ref innerhalb des Codes ?⓪(BCC.W bad⓪(MOVE.L 0(A4,D1.L),D0 ;ItemAdr im Modul nachtragen⓪(MOVE.L D2,0(A4,D1.L)⓪ ⓪(MOVE.L (A7),A6⓪(MOVE.L A1,-(A7)⓪(MOVE.L myMod(A6),A5⓪(MOVE.L D1,D4⓪(ADD.L tModDesc.codead(A5),D4⓪(SUB.L tModDesc.diff(A5),D4⓪ ⓪(MOVE.L lastDrop,A5⓪(CMPA.L eoLists,A5⓪(BCC relerr1⓪(MOVE.L D4,(A5)⓪(MOVE listIndex,D4⓪(SUBQ #1,D4⓪(ASL #2,D4⓪(MOVE.L ListTop,A1⓪(MOVE.L A5,0(A1,D4.W)⓪(MOVE.L ListBeg,A1⓪(TST.L 0(A1,D4.W)⓪(BNE.S cont2⓪(MOVE.L A5,0(A1,D4.W)⓪&cont2⓪(ADDQ.L #4,lastDrop⓪ ⓪(MOVE.L (A7)+,A1⓪(MOVE.L imMod(A6),A6 ;A6 ist ^ModLst^ [ImIndex]⓪ ⓪(MOVE.L D0,D1⓪(BNE RE11⓪(BRA RE6⓪ ⓪&relerr2⓪(JMP RelError2⓪&relerr1⓪(CLR (A3)+⓪(JMP RelError⓪ ⓪!!bad CLR.W D6 ;FehlerFlag⓪!!RE5 MOVE.L (A7)+,A6 ;A6 wieder reparieren⓪(MOVE.L ImPtr(A6),A0⓪(MOVE.L A1,(A0)⓪(MOVE.L ok(A6),A0⓪(MOVE.W D6,(A0)⓪ ⓪(MOVEM.L (A7)+,D3/D4/D6/A4/A5⓪&END⓪$END reloc;⓪ ⓪"(*$R+,L+*)⓪"PROCEDURE Relocate ( myIndex: tIndex ) : Boolean;⓪"⓪$VAR v: LongCard;⓪)ImPtr: address;⓪'ImIndex: tIndex;⓪,ok: boolean;⓪-i: cardinal;⓪!main, importn: tModName;⓪(ptrMod: ptrModDesc;⓪(⓪$BEGIN⓪&(*** Zuerst die Var/Proc-Liste abarbeiten ***)⓪&⓪&ptrMod:= ADR (ModLst^ [myIndex]);⓪&Assign (ptrMod^.name, main, ok);⓪&ClrList;⓪&⓪&ASSEMBLER⓪/MOVEM.L D3/D4/D5/D6/A4/A5/A6,-(A7)⓪/MOVE.L ListTop,D4⓪/MOVE.L ListBeg,D5⓪/MOVE.W ListIndex,D6⓪/MOVE D6,D3⓪/SUBQ #1,D3⓪/ASL #2,D3⓪/MOVE.L lastDrop,A5⓪/MOVE.L ptrMod(A6),A1⓪ ⓪/MOVE.L tModDesc.image(A1),A4 ;A4 zeigt auf Modul-Bild im RAM⓪/MOVE.L 22(A4),A0 ;^Var/ProcListe⓪/ADDA.L A4,A0⓪(!RE3 MOVE.L (A0)+,D0 ;^letzte Ref⓪/BEQ.W RE1 ;Ende der Liste⓪/⓪/MOVE.L (A0)+,D1 ;rel. Adresse⓪/BEQ re3 ;wurde wegoptimiert⓪ ⓪/CMP.W ListMax,D6 ;ListIndex⓪/BCC.W relerr2b⓪/ADDQ #1,D6 ;ListIndex⓪/ADDQ #4,D3⓪/MOVE.L D5,A6⓪/CLR.L 0(A6,D3.W)⓪ ⓪/CMP.L 22(A4),D1⓪/BCC isVar ;das ist eine Var-Referenz⓪/ADD.L tModDesc.codeAd(A1),D1 ;Prozeduren: + Modulanfang⓪/SUB.L tModDesc.diff(A1),D1 ; - Importlisten-Laenge⓪/BRA RE2⓪(!isVar ADD.L tModDesc.varAd(A1),D1 ;Variablen: + VarAnfang⓪/ADD.L BSSstart,D1 ;Codelänge addieren⓪/SUB.L 22(A4),D1⓪(!RE2 CMP.L 22(A4),D0 ;liegt Ref innerhalb des Codes ?⓪/BCC.S bad2⓪/MOVE.L 0(A4,D0.L),D2 ;^naechste Ref⓪/MOVE.L D1,0(A4,D0.L) ;Adresse eintragen⓪ ⓪/ADD.L tModDesc.codead(A1),D0⓪/SUB.L tModDesc.diff(A1),D0⓪ ⓪/CMPA.L eoLists,A5⓪/BCC.S relerr⓪/MOVE.L D0,(A5)⓪/MOVE.L D4,A6⓪/MOVE.L A5,0(A6,D3.W)⓪/MOVE.L D5,A6⓪/TST.L 0(A6,D3.W)⓪/BNE.S cont⓪/MOVE.L A5,0(A6,D3.W)⓪-cont⓪/ADDQ.L #4,A5⓪ ⓪/MOVE.L D2,D0⓪/BNE RE2 ;weitere Refs auf dieses Objekt⓪/BRA RE3 ;pruefe, ob weitere Objekte⓪ ⓪-relerr⓪/CLR (A3)+⓪/JMP RelError⓪-relerr2b⓪/JMP RelError2⓪ ⓪(!bad2⓪/MOVE.W D6,ListIndex⓪/MOVE.L A5,lastDrop⓪/MOVEM.L (A7)+,D3/D4/D5/D6/A4/A5/A6⓪/END; error ('',main,relocerr); ASSEMBLER⓪/BRA RE0⓪ ⓪(!RE1 MOVE.L A5,lastDrop⓪/MOVE.W D6,ListIndex⓪/MOVEM.L (A7)+,D3/D4/D5/D6/A4/A5/A6⓪)RE0⓪&END;⓪ ⓪((*** Jetzt kümmern wir uns um die Importe ***)⓪&⓪&WITH ptrMod^ DO⓪(ImPtr:= image + entry (image, 14); (* ^ImportListe *)⓪(i:= 1;⓪(ok:= TRUE;⓪(WHILE ( i <= ImpIndex ) & ok DO⓪*inc (ImPtr, 4);⓪*Skipstr (ImPtr); (* ImPtr hinter Namen setzen *)⓪*ImIndex:= ImpLst^[i];⓪*Assign (ModLst^ [ImIndex].name, importn, ok);⓪*reloc (ptrMod, ADR (ModLst^ [ImIndex]), ImPtr, ok);⓪*IF ~ok THEN error (importn,main,relocerr) END;⓪*inc(i)⓪(END; (* alle Importe abgearbeitet *)⓪&END; (* with ModLst^ [myIndex] *)⓪ ⓪&(* Alle f. dieses Modul relozierten Adressen in RelTab eintragen *)⓪&⓪&v:= SmallestInList();⓪&WHILE v # 0L DO⓪(PutIntoRelTab(v);⓪(v:= SmallestInList()⓪&END;⓪&⓪&RETURN ok⓪$END Relocate;⓪ ⓪ ⓪"PROCEDURE setCodeAd;⓪$VAR i: tIndex;⓪$BEGIN⓪&FOR i:= 1 TO ModIndex DO⓪(WITH ModLst^ [i] DO⓪*IF useCode THEN⓪,modlen:= codeEnd - diff;⓪,codeAd:= CodeNow;⓪,CodeNow:= CodeNow + modlen⓪*ELSE⓪,ClearMod (i);⓪,DEC (UsedCodes);⓪,DEC (UsedInits);⓪,modlen:= 0⓪*END⓪(END⓪&END;⓪$END setCodeAd;⓪ ⓪ ⓪"PROCEDURE AnotherMod ():BOOLEAN;⓪$VAR c:CHAR;⓪$BEGIN⓪&Prompt (1, 'Another module (Y/N) ? ');⓪&REPEAT⓪(Read (c);⓪(c:=CAP(c);⓪&UNTIL (c='Y') OR (c='N') OR (c=33C) OR (c=15C);⓪&RETURN (c='Y') OR (c=15C)⓪$END AnotherMod;⓪"⓪"VAR i,j: cardinal;⓪*ln: INTEGER;⓪%DriveNr: Cardinal;⓪'VolNr: Cardinal;⓪)len: Cardinal;⓪+f: file;⓪%ModName: string;⓪&outsuf: String;⓪+s: string;⓪$outFirst: boolean;⓪%inFirst: boolean;⓪(argc: CARDINAL;⓪(argv: ARRAY [0..9] OF PtrArgStr;⓪%modIdx2: tIndex;⓪$firstMod: BOOLEAN;⓪#linkCount: CARDINAL;⓪%gotLast: BOOLEAN;⓪%tabSize: LONGCARD;⓪$l, avail: LONGINT;⓪%outName: string; (* Name des Codefiles *)⓪ ⓪"BEGIN (* of Dialog *)⓪$optProcs:= FALSE;⓪$noHeader:= FALSE;⓪$noShModLst:= FALSE;⓪$noProcSyms:= FALSE;⓪$outname:= '';⓪$HeaderFlags:= {};⓪$InitArgCV (argc,argv);⓪$FOR i:= 1 TO argc-1 DO⓪&Assign (argv[i]^, s, ok);⓪&Upper (s);⓪&IF (s[0] = '-') OR (s[0] = '/') THEN⓪(CASE s[1] OF⓪(| '0'..'9':⓪,j:= 1;⓪,INCL (HeaderFlags, StrConv.StrToCard (s,j,ok));⓪(| 'R':⓪,j:= 2;⓪,j:= StrConv.StrToCard (s,j,ok);⓪,IF j >= 100 THEN ListMax:= j END;⓪(| 'H':⓪,optProcs:= TRUE;⓪(| 'F':⓪,optProcs:= TRUE;⓪,noHeader:= TRUE;⓪,noShModLst:= TRUE;⓪,noProcSyms:= TRUE;⓪(| 'M':⓪,noProcSyms:= TRUE;⓪(| 'V':⓪,VerboseOutput;⓪(| 'O':⓪,IF s[2] # 0C THEN⓪.(* Output name directly appended *)⓪.INC (argv[i], 2);⓪.FastStrings.Assign (argv[i]^, outname);⓪,ELSIF i < argc-1 THEN⓪.(* Output name in next word *)⓪.FastStrings.Assign (argv[i+1]^, outname);⓪,END⓪(ELSE⓪*ReportError (conc ('Illegal option character: ', s[1]));⓪(END;⓪(argv[i]^[0]:= 0C⓪&END⓪$END;⓪$ClearEOP;⓪$⓪$CodeNow:= 18 + LENGTH (CodeID) + 1 + SysVarSpace;⓪F(* Platz fuer Start-LEA's/JMP und PDB *)⓪$VarNow:= 0L;⓪$BodyLen:= 0;⓪$⓪$ModIndex:= 0;⓪$modIdx2:=0;⓪$firstMod:= TRUE;⓪$linkCount:= MIN (LLRange);⓪$gotLast:= FALSE;⓪$LOOP⓪&inFirst:= TRUE;⓪&REPEAT⓪(Prompt (1, 'Module name? ');⓪(ReadString (ModName);⓪(inFirst:= FALSE;⓪(IF length (ModName) = 0 THEN⓪*Remove (outfile);⓪*RETURN false⓪(ELSIF NOT hasSuffix (ModName) THEN⓪*ConcatName (modname, DefPrgInSuf, modname);⓪(END;⓪(DiscardMods (modIdx2);⓪(Report (1, 'Module name: ');⓪(WriteString (ModName);⓪(IF firstMod THEN⓪*singleMod:= TRUE;⓪*InitIndex:= 0;⓪*ClearEOP;⓪(END;⓪((* Release geladene Moduln: *)⓪(WHILE ModIndex # modIdx2 DO⓪*DeAllocate (ModLst^ [ModIndex].ImpLst,0L);⓪*DeAllocate (ModLst^ [ModIndex].image,0L);⓪*DEC (ModIndex)⓪(END;⓪(LoadingMain:= TRUE;⓪(CodeSuffix:= false⓪&UNTIL ExecMod (modname, anykey, BadIndex) # BadIndex;⓪&IF firstMod THEN⓪(InitIdx2:= InitIndex⓪&END;⓪&IF (argc>=2) & gotLast THEN⓪(EXIT⓪&END;⓪&IF (argc<2) & ~AnotherMod () THEN⓪(EXIT⓪&END;⓪&modIdx2:= ModIndex;⓪&firstMod:= FALSE⓪$END;⓪$⓪$(* Alles geladen, nun kann alles reloziert werden *)⓪$⓪$Vergleiche;⓪$⓪$HALT;⓪$RETURN TRUE⓪"END dialog;⓪ ⓪ VAR dummy: PDB;⓪$ch: CHAR;⓪ ⓪ BEGIN (* ROMLoad *)⓪"IF SIZE (dummy.ModLst^[1]) # ShModLstSpace THEN HALT END;⓪"IF TSIZE (PDB) # SysVarSpace THEN HALT END;⓪"IF NOT ODD (LENGTH (CodeID)) THEN HALT END;⓪"⓪"IF LinkerParm.maxLinkMod >= (MAX (tIndex)-1) THEN⓪$LinkerParm.maxLinkMod:= MAX (tIndex)-2⓪"END;⓪"IF LinkerParm.maxLinkMod = 0 THEN LinkerParm.maxLinkMod:= 100 END;⓪"ListMax:= 1000;⓪"⓪"InitOutput (LinkerParm.maxLinkMod, conc ('Megamax Modula-2 Linker ',version));⓪"⓪"HomePath:= ShellPath; ⓪"⓪"ALLOCATE (ModLst, TSIZE (tModDesc) * LONG (LinkerParm.maxLinkMod+2));⓪"ALLOCATE (InitLst, TSIZE (tIndex) * LONG (LinkerParm.maxLinkMod+2));⓪"IF (ModLst = NIL) OR (ModLst = NIL) THEN⓪$ReportError ('Out of memory');⓪$TermProcess (MOSGlobals.OutOfMemory)⓪"END;⓪"DefPrgInSuf:= DftSfx;⓪"DefImpInSuf:= ImpSfx;⓪"RelocTab:= NIL;⓪"pRelTab:= NIL;⓪"firstRelVal:= 0L;⓪"lastRelVal:= 0L;⓪"realForm:= 0;⓪"extendedCode:= FALSE;⓪"IF dialog() THEN⓪"END;⓪ END CmpMods2.⓪ ə
- (* $FFF20C02$FFF698A3$FFFD709E$FFFD709E$FFFD709E$FFFD709E$FFFD709E$FFFD709E$FFFD709E$FFFD709E$FFFD709E$FFFD709E$FFFD709E$FFFD709E$FFFD709E$FFE7FB26$FFFD709E$FFFD709E$FFFD709E$FFFD709E$00006FEC$FFFD709E$FFFD709E$FFFD709E$FFFD709E$FFFD709E$FFF6AA4D$FFE7FB26$FFFD709E$FFE7FB26$FFFD709E$FFE7FB26$FFFD709E$FFFD709E$00002111$FFFD709E$FFF6AAC9$FFFD709E$FFE7FB26$FFFD709E$FFFD709E$FFFD709EÇ$00003171T.......T.......T.......T.......T.......T.......T.......T.......T.......T.......$000030BD$0000317E$00003197$000031B1$000031E1$000031F1$000031FB$00003208$00000093$00000078$00003171$00003315$0000316E$000031D4$0000313F$0000314FÕÇâ*)
-